home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / powervww / pvscroll.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-01-05  |  9.8 KB  |  399 lines

  1. //  ____________________________________________________
  2. // |                                                    |
  3. // |  Project:     POWER VIEW INTERFACE                 |
  4. // |  File:        PVSCROLL.CPP                         |
  5. // |  Compiler:    WPP386 (10.6)                        |
  6. // |                                                    |
  7. // |  Subject:     Scroll bar implementation            |
  8. // |                                                    |
  9. // |  Author:      Emil Dotchevski                      |
  10. // |____________________________________________________|
  11. //
  12. // E-mail: zajo@geocities.com
  13. // URL:    http://www.geocities.com/SiliconValley/Bay/3577
  14.  
  15. #define uses_cmd
  16. #define uses_dc
  17. #define uses_icons
  18. #define uses_scroll
  19.  
  20. #include "PVuses.h"
  21.  
  22. #ifndef NOMOUSE
  23. static int delta_x = 0;
  24. static int delta_y = 0;
  25. #endif
  26.  
  27. //Tscroll_bar publics:
  28.  
  29. Tscroll_bar::Tscroll_bar( int _xl, int _yl, uint &_count, uint &_beg_print ):
  30.   Titem( _xl, _yl )
  31. {
  32.   set_flags( ifSELECTABLE, 0 ); set_flags( sfHIDEABLE, 1 );
  33.   set_state( isON_TOP, 1 );
  34. #ifndef NOMOUSE
  35.   set_events_mask( evMOUSE_REP, 1 );
  36. #endif
  37.   count = &_count;
  38.   beg_print = &_beg_print;
  39.   max_print = NULL;
  40.   delta = 0;
  41. }
  42.  
  43. void Tscroll_bar::set_flags( uint _flags_word, boolean enable )
  44. {
  45.   Titem::set_flags( _flags_word, enable );
  46.   if( !( _flags_word & sfHANDLE_KEYBOARD ) ) return;
  47.   icon_up->set_events_mask( evKEY_PRESS, flags( sfHANDLE_KEYBOARD ) );
  48.   icon_down->set_events_mask( evKEY_PRESS, flags( sfHANDLE_KEYBOARD ) );
  49. }
  50.  
  51. void Tscroll_bar::update( void )
  52. {
  53.   do_update();
  54.   if( flags(sfHIDEABLE) )
  55.     set_state( isHIDDEN, *count <= ( *max_print + delta ) );
  56.   else
  57.     if( state(isHIDDEN) ) set_state( isHIDDEN, 0 );
  58. }
  59.  
  60. //Tscroll_bar protected:
  61.  
  62. void Tscroll_bar::do_update( void )
  63. {
  64.   char sb_len;
  65.  
  66.   sb_len = get_bar_length();
  67.   if( *count <= ( *max_print + delta ) )
  68.   {
  69.     sb_length = sb_len;
  70.     sb_begin = 0;
  71.   }
  72.   else
  73.     if( *count && sb_len )
  74.     {
  75.       sb_length = (char) (( ( *max_print + delta ) * sb_len ) / *count);
  76.       if( ( sb_length == sb_len ) && ( *count > sb_len ) && ( sb_len > 1 ) ) sb_length--;
  77.       if( !sb_length ) sb_length++;
  78.       sb_begin = (char)( ( *beg_print * sb_len + ( *count>>1 ) ) / *count );
  79.       if( ( ( sb_begin + sb_length ) > sb_len ) ||
  80.           ( ( *beg_print + ( *max_print + delta ) ) == *count ) )
  81.         sb_begin = (char) ( sb_len - sb_length );
  82.     }
  83.     else
  84.     {
  85.       sb_begin = 0;
  86.       sb_length = 0;
  87.     }
  88. }
  89.  
  90. void Tscroll_bar::event_handler( Tevent &ev )
  91. {
  92.   Titem::event_handler( ev );
  93.   if( state( isHIDDEN ) || owner->state( isICONIZED ) ) goto ret;
  94.   switch( ev.code )
  95.   {
  96.     case evCOMMAND:
  97.       switch( ev.CMD_CODE )
  98.       {
  99.         case cmUP_ARROW:
  100.         case cmDOWN_ARROW:
  101.           if( owner->state(isACCESSABLE) || !owner->event_mask )
  102.           {
  103.             if( owner->flags( ifSELECTABLE ) && owner->state( isALIVE ) && !owner->state( isFOCUSED ) ) owner->focus();
  104.             if( ev.CMD_CODE==cmUP_ARROW ) up(); else down();
  105.             handled( ev );
  106.             owner->redraw();
  107.             if( flags(sfNOTICE) ) message(owner,cmSCROLL_BAR);
  108.           }
  109.       }
  110.       break;
  111. #ifndef NOMOUSE
  112.     case evMOUSE_DOWN:
  113.       if( ev.INSIDE )
  114.       {
  115.         owner->focus();
  116.         if( mouse_on_bar( ev ) && ( ( *max_print + delta ) < *count ) )
  117.         {
  118.           delta_x = ev.LOCAL_X - sb_begin;
  119.           delta_y = ev.LOCAL_Y - sb_begin;
  120.           while( get_mouse( ev, evMOUSE_DRAG ) )
  121.           {
  122.             goto_bar( ev );
  123.             owner->redraw();
  124.             if( flags(sfNOTICE) ) message(owner,cmSCROLL_BAR);
  125.           }
  126.         }
  127.         else
  128.         {
  129.           boolean f = mouse_on_pgup( ev );
  130.           do
  131.           {
  132.             if( f ) page_up(); else page_down();
  133.             update();
  134.             owner->redraw();
  135.             if( flags(sfNOTICE) ) message(owner,cmSCROLL_BAR);
  136.           }
  137.           while( ev.INSIDE && get_mouse( ev, evMOUSE_REP ) );
  138.         }
  139.         handled( ev );
  140.       }
  141.       break;
  142. #endif
  143.   }
  144.   ret: update();
  145. }
  146.  
  147. void Tscroll_bar::up( void )
  148. {
  149.   if( *beg_print ) ( *beg_print )--;
  150. }
  151.  
  152. void Tscroll_bar::down( void )
  153. {
  154.   if( *count > ( *max_print + delta ) )
  155.     if( *beg_print < *count - ( *max_print + delta ) ) ( *beg_print )++;
  156. }
  157.  
  158. void Tscroll_bar::page_up( void )
  159. {
  160.   if( *beg_print > ( *max_print + delta ) )
  161.     ( *beg_print ) -= ( *max_print + delta ) - 1;
  162.   else
  163.     *beg_print = 0;
  164. }
  165.  
  166. void Tscroll_bar::page_down( void )
  167. {
  168.   uint xx;
  169.  
  170.   if( *count > ( *max_print + delta ) )
  171.   {
  172.     xx = *count - ( *max_print + delta );
  173.     *beg_print += ( *max_print + delta ) - 1;
  174.     if( *beg_print >= xx ) *beg_print = xx;
  175.   }
  176. }
  177.  
  178. void Tscroll_bar::home( void )
  179. {
  180.   *beg_print = 0;
  181. }
  182.  
  183. void Tscroll_bar::end( void )
  184. {
  185.   if( ( *max_print + delta ) < *count )
  186.     *beg_print = *count - ( *max_print + delta );
  187.   else
  188.     *beg_print = 0;
  189. }
  190.  
  191. //Tvscroll_bar publics:
  192.  
  193. Tvscroll_bar::Tvscroll_bar( int _len, uint &_count, uint &_beg_print ):
  194.   Tscroll_bar( i_sb_up_len, _len -= 2, _count, _beg_print )
  195. {
  196.   icon_up = NEW( Ticon( i_sb_up,  cmUP_ARROW,  kUP ) );
  197.     icon_up->set_flags( bfREPEAT, 1 );
  198.     put_in( icon_up, 0, -1 );
  199.   icon_down = NEW( Ticon( i_sb_down,cmDOWN_ARROW,kDOWN ) );
  200.     icon_down->set_flags( bfREPEAT, 1 );
  201.     icon_down->drag_mode = dmDRAG_VER;
  202.     put_in( icon_down, 0, _len );
  203.   grow_mode = gmGROW_VER; drag_mode = dmDRAG_HOR;
  204. }
  205.  
  206. //Tvscroll_bar protected:
  207.  
  208. void Tvscroll_bar::calc_bounds( int delta_xl, int delta_yl )
  209. {
  210.   update();
  211.   if( i_sb_up_len != xl )
  212.   {
  213.     drag( x + ( xl - i_sb_up_len ), y );
  214.     resize( i_sb_up_len, yl );
  215.   }
  216.   Tscroll_bar::calc_bounds( delta_xl, delta_yl );
  217. }
  218.  
  219. void Tvscroll_bar::draw( void )
  220. {
  221.   char c, s;
  222.  
  223.   do_update();
  224.   if( window_state( isACTIVE ) ) s = '1'; else s = '0';
  225.   c = (char) ( yl - sb_begin - sb_length );
  226.   txtf( "|%c%s|l%c%s|l%c%s|l%c", s, i_vsb_blank, sb_begin, i_vsb_bar, sb_length, i_vsb_blank, c );
  227. }
  228.  
  229. void Tvscroll_bar::initialize( void )
  230. {
  231.   Tscroll_bar::initialize();
  232.   if( max_print == NULL ) max_print = &owner->yl;
  233.   drag( x, y + 1 );
  234.   update();
  235. }
  236.  
  237. void Tvscroll_bar::event_handler( Tevent &ev )
  238. {
  239.   Tscroll_bar::event_handler( ev );
  240.   if( ( ev.code == evKEY_PRESS ) && flags( sfHANDLE_KEYBOARD ) )
  241.   {
  242.     switch( ev.ASCII )
  243.     {
  244.       case kHOME:
  245.         home(); break;
  246.       case kEND:
  247.         end(); break;
  248.       case kPG_UP:
  249.         page_up(); break;
  250.       case kPG_DN:
  251.         page_down(); break;
  252.       default:
  253.         return;
  254.     }
  255.     handled( ev );
  256.   }
  257. }
  258.  
  259. //Tvscroll_bar private:
  260.  
  261. #ifndef NOMOUSE
  262. boolean Tvscroll_bar::mouse_on_pgup( Tevent &ev )
  263. {
  264.   return ( ev.LOCAL_Y >= 0 ) && ( ev.LOCAL_Y < sb_begin );
  265. }
  266.  
  267. boolean Tvscroll_bar::mouse_on_pgdn( Tevent &ev )
  268. {
  269.   return ( ev.LOCAL_Y >= ( sb_begin + sb_length ) ) && ( ev.LOCAL_Y <= yl );
  270. }
  271.  
  272. boolean Tvscroll_bar::mouse_on_bar( Tevent &ev )
  273. {
  274.   return ( ev.LOCAL_Y >= sb_begin ) && ( ev.LOCAL_Y < ( sb_begin + sb_length ) );
  275. }
  276.  
  277. void Tvscroll_bar::goto_bar( Tevent &ev )
  278. {
  279.   int xx;
  280.   char old;
  281.  
  282.   old = sb_begin;
  283.   xx = ev.LOCAL_Y - delta_y;
  284.   if( xx<0 )
  285.     sb_begin = 0;
  286.   else
  287.     sb_begin = (char) xx;
  288.   xx = yl - sb_length;
  289.   if( sb_begin > xx ) sb_begin = (char) xx;
  290.   if( sb_begin == old ) return;
  291.   if( sb_begin < xx )
  292.     *beg_print = ( sb_begin * *count ) / yl;
  293.   else
  294.     *beg_print = *count - ( *max_print + delta );
  295. }
  296. #endif
  297.  
  298. char Tvscroll_bar::get_bar_length( void )
  299. {
  300.   return (char) yl;
  301. }
  302.  
  303. //Thscroll_bar publics:
  304.  
  305. Thscroll_bar::Thscroll_bar( int _len, uint &_count, uint &_beg_print ):
  306.   Tscroll_bar( _len -= (i_sb_left_len + i_sb_right_len), 1, _count, _beg_print )
  307. {
  308.   icon_up = NEW( Ticon( i_sb_left, cmUP_ARROW,  kLEFT ) );
  309.     icon_up->set_flags( bfREPEAT, 1 );
  310.     put_in( icon_up, -i_sb_left_len, 0 );
  311.   icon_down = NEW( Ticon( i_sb_right, cmDOWN_ARROW, kRIGHT ) );
  312.     icon_down->set_flags( bfREPEAT, 1 );
  313.     icon_down->drag_mode = dmDRAG_HOR;
  314.     put_in( icon_down, _len, 0 );
  315.   grow_mode = gmGROW_HOR; drag_mode = dmDRAG_VER;
  316. }
  317.  
  318. //Thscroll_bar potected:
  319.  
  320. void Thscroll_bar::calc_bounds( int delta_xl, int delta_yl )
  321. {
  322.   int xx;
  323.  
  324.   update();
  325.   if( i_sb_left_len != -icon_up->x )
  326.   {
  327.     xx = icon_up->x + i_sb_left_len;
  328.     drag( x + xx, y );
  329.     resize( xl - xx - xx - xx, 1 );
  330.     icon_up->drag( -i_sb_left_len, 0 );
  331.     icon_down->drag( xl, 0 );
  332.   }
  333.   Tscroll_bar::calc_bounds( delta_xl, delta_yl );
  334. }
  335.  
  336. void Thscroll_bar::draw( void )
  337. {
  338.   char c, s;
  339.  
  340.   do_update();
  341.   if( window_state( isACTIVE ) ) s = '1'; else s = '0';
  342.   c = (char) ( xl - sb_begin - sb_length );
  343.   txtf( "|%c|r%c%s|r%c%s|r%c%s", s, sb_begin, i_hsb_blank, sb_length, i_hsb_bar, c, i_hsb_blank );
  344. }
  345.  
  346. void Thscroll_bar::initialize( void )
  347. {
  348.   Tscroll_bar::initialize();
  349.   if( max_print == NULL ) max_print = &owner->xl;
  350.   drag( x + i_sb_left_len, y );
  351.   update();
  352. }
  353.  
  354. //Thscroll_bar private:
  355.  
  356. #ifndef NOMOUSE
  357. boolean Thscroll_bar::mouse_on_pgup( Tevent &ev )
  358. {
  359.   return ( ev.LOCAL_X >= 0 ) && ( ev.LOCAL_X < sb_begin );
  360. }
  361.  
  362. boolean Thscroll_bar::mouse_on_pgdn( Tevent &ev )
  363. {
  364.   return ( ev.LOCAL_X >= ( sb_begin + sb_length ) ) && ( ev.LOCAL_X <= xl );
  365. }
  366.  
  367. boolean Thscroll_bar::mouse_on_bar( Tevent &ev )
  368. {
  369.   return ( ev.LOCAL_X >= sb_begin ) && ( ev.LOCAL_X < ( sb_begin + sb_length ) );
  370. }
  371.  
  372. void Thscroll_bar::goto_bar( Tevent &ev )
  373. {
  374.   int xx;
  375.   char old;
  376.  
  377.   old = sb_begin;
  378.   xx = ev.LOCAL_X - delta_x;
  379.   if( xx < 0 )
  380.     sb_begin = 0;
  381.   else
  382.     sb_begin = (char) xx;
  383.   if( sb_begin == old ) return;
  384.   xx = xl - sb_length;
  385.   if( sb_begin < xx )
  386.     *beg_print = ( sb_begin * *count ) / xl;
  387.   else
  388.   {
  389.     sb_begin = (char) xx;
  390.     *beg_print = *count - ( *max_print + delta );
  391.   }
  392. }
  393. #endif
  394.  
  395. char Thscroll_bar::get_bar_length( void )
  396. {
  397.   return (char) xl;
  398. }
  399.